<!DOCTYPE html>
<div contenteditable dir="ltr">&#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502; &#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502;</div>
<div contenteditable dir="ltr">this is some ltr text in an rtl container</div>
<div contenteditable dir="rtl">&#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502; &#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502;</div>
<div contenteditable dir="rtl">this is some ltr text in an rtl container</div>
<pre id="console"></pre>

<script>
function log(text)
{
    document.getElementById("console").appendChild(document.createTextNode(text + "\n"));
}

function showNode(node)
{
    var tagName = node.tagName ? node.tagName : "TEXT";
    return "<" + tagName + ">" + node.textContent + "</" + tagName + ">";
}

function assertSelectionEquals(expectedNode, expectedBaseOffset, expectedExtentOffset, message)
{
    var selection = getSelection();
    if (selection.baseNode !== expectedNode
            || selection.baseOffset !== expectedBaseOffset
            || selection.extentNode !== expectedNode
            || selection.extentOffset !== expectedExtentOffset)
        log("FAIL (" + message + "):\n" +
            "     expected base offset " + expectedBaseOffset + " in node " + showNode(expectedNode) + "\n" +
            "        and extent offset " + expectedExtentOffset + " in node " + showNode(expectedNode) + "\n" +
            "  ... but got base offset " + selection.baseOffset + " in node " + showNode(selection.baseNode) + "\n" +
            "        and extent offset " + selection.extentOffset + " in node " + showNode(selection.extentNode));
    else
        log("PASS (" + message + ")");
}

function runTestForContainer(container)
{
    log("Testing " + container.dir + " container with contents \"" + container.textContent + "\":");

    var textNode = container.childNodes[0];
    var rightmostOffset = container.dir === "rtl" ? 0 : textNode.length;
    var leftmostOffset = container.dir === "rtl" ? textNode.length : 0;

    getSelection().collapse(textNode, leftmostOffset);
    getSelection().modify("extend", "left", "lineboundary");
    assertSelectionEquals(textNode, leftmostOffset, leftmostOffset, "extend left from left");
    getSelection().modify("extend", "left", "lineboundary");
    assertSelectionEquals(textNode, leftmostOffset, leftmostOffset, "extend left from left again");

    getSelection().collapse(textNode, leftmostOffset);
    getSelection().modify("extend", "right", "lineboundary");
    assertSelectionEquals(textNode, leftmostOffset, rightmostOffset, "extend right from left");
    getSelection().modify("extend", "right", "lineboundary");
    assertSelectionEquals(textNode, leftmostOffset, rightmostOffset, "extend right from left again");

    getSelection().collapse(textNode, rightmostOffset);
    getSelection().modify("extend", "right", "lineboundary");
    assertSelectionEquals(textNode, rightmostOffset, rightmostOffset, "extend right from right");
    getSelection().modify("extend", "right", "lineboundary");
    assertSelectionEquals(textNode, rightmostOffset, rightmostOffset, "extend right from right again");

    getSelection().collapse(textNode, rightmostOffset);
    getSelection().modify("extend", "left", "lineboundary");
    assertSelectionEquals(textNode, rightmostOffset, leftmostOffset, "extend left from right");
    getSelection().modify("extend", "left", "lineboundary");
    assertSelectionEquals(textNode, rightmostOffset, leftmostOffset, "extend left from right again");

    log("");
}

var testContainers = document.getElementsByTagName("div");
for (var i = 0; i < testContainers.length; i++)
    runTestForContainer(testContainers[i]);

if (window.testRunner) {
    while (testContainers.length > 0)
        document.body.removeChild(testContainers[0]);
    testRunner.dumpAsText();
}
</script>
